/*******************************************************************************
**
** Copyright (c) 2011 - The OWE Team
**
** This file is part of OWE.
**
** OWE is a free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; version
** version 2.1 of the License.
**
** OWE is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public
** License along with OWE. If not, see <http://www.gnu.org/licenses/>.
**
*******************************************************************************/

#include <QDomDocument>
#include <QFile>
#include <QString>

#include <owe/configparser.h>
#include <owe/node.h>
#include <owe/ustring.h>
#include <owe/widgetelement.h>

#include "configparser_p.h"
#include "xmlnode.h"

OWE_USE_NAMESPACE

ConfigParserPrivate::ConfigParserPrivate(const UString &path)
    : valid(true)
    , maxDepth(2)
    , path(path)
    , widgetElement(0)
{
    valid = parse();
}

ConfigParserPrivate::~ConfigParserPrivate()
{
    delete widgetElement;
}

bool ConfigParserPrivate::parse()
{
    QFile file(path.data());
    if (!file.open(QIODevice::ReadOnly))
        return false;

    doc = QDomDocument("config");
    if (!doc.setContent(&file))
        return false;

    file.close();

    QDomNode rootElement = doc.documentElement();

    XMLNode *node = new XMLNode(rootElement);
    Element *element = Element::fromNode(node);
    delete node;

    if (element->type() != Element::Widget) {
        delete element;
        return false;
    }

    widgetElement = static_cast<WidgetElement *>(element);

    recursiveParse(widgetElement, rootElement.firstChild());

    return true;
}

void ConfigParserPrivate::recursiveParse(Element *parent,
        QDomNode current, int depth)
{
    while (!current.isNull()) {
        XMLNode *currentNode = new XMLNode(current);
        Element *currentElement = Element::fromNode(currentNode);
        delete currentNode;

        bool accepted = parent->addChild(currentElement);

        if (accepted && depth < maxDepth && current.hasChildNodes())
            recursiveParse(currentElement, current.firstChild(), depth + 1);

        current = current.nextSibling();
    }
}

ConfigParser::ConfigParser(const UString &path)
    : d_ptr(new ConfigParserPrivate(path))
{
}

ConfigParser::~ConfigParser()
{
    delete d_ptr;
}

bool ConfigParser::isValid() const
{
    return d_ptr->valid;
}

const WidgetElement *ConfigParser::widgetElement() const
{
    return d_ptr->widgetElement;
}
